package com.sun.jdk.date.jdk8after;

import java.time.*;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

/**
 * 练习
 * 作者：一双看向未来的眼睛
 * 链接：https://www.jianshu.com/p/20bfae706882
 * 来源：简书
 */
public class Java8TimeClassMethodDemo2 {

    private static void test1() {
        // 1. 创建当前时间(不带时区)
        LocalDateTime localDateTimeNow = LocalDateTime.now();
        System.out.println("localDateTime = " + localDateTimeNow);

        // 2. 创建当前时间(只包含年月日，不带时区)
        LocalDate localDateNow = LocalDate.now();
        System.out.println("localDate = " + localDateNow);

        // 3. 创建当前时间(包含年月日时分秒并且带有时区)
        ZonedDateTime zonedDateTimeNow = ZonedDateTime.now();
        System.out.println("zonedDateTimeNow = " + zonedDateTimeNow);

        // 4. 创建2022年7月12日19点23份7秒的日期对象，月份用枚举值表示
        LocalDateTime localDateTime = LocalDateTime.of(2022, Month.JULY, 23, 19, 23, 7);
        System.out.println("localDateTime = " + localDateTime);

        // 5. 创建2022年7月12日的日期对象，月份使用枚举表示
        LocalDate localDate = LocalDate.of(2022, Month.JULY, 23);
        System.out.println("localDate = " + localDate);

        // 6. 创建9点23份7秒的日期时间对象
        LocalTime localTime = LocalTime.of(19, 23, 7);
        System.out.println("localTime = " + localTime);
    }

    private static void test2(){
        // 出发点：我直接使用LocalDateTime.now()方法获取的当前电脑系统中默认的时区的日期时间值
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println("localDateTime = " + localDateTime);

        // 疑问点：如果我想知道其他时区的LocalDateTime.now()对应的时间怎么获取呢？
        LocalDateTime localDateTimeOfTokyo = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
        System.out.println("localDateTimeOfTokyo = " + localDateTimeOfTokyo);
    }

    /**
     * plus和minus在LocalDate中的应用
     * 想要修改某个日期/时间对象的现有实例时，我们可以使用 plus和 minus方法来完成操作。
     *
     * Java8中日期时间相关的API中的所有实例都是不可改变的，一旦创建LocalDate，LocalTime，LocalDateTime就无法修改他们（类似于String），
     * 这对于线程安全时非常有利的。
     *
     * plus方法在LocalDate与LocalTime中的使用
     *
     *  LocalDate中定义了多种对日期进行增减操作的方法。
     *
     * LocalDate plusDay(long days) 增加天数
     *
     * LocalDate plusWeeks(long weeks) 增加周数
     *
     * LocallDate plusMonths(long months) 增加月数
     *
     * LocalDate plusYears(long years) 增加年数
     *
     */

    private static void test3(){
        // 封装LocalDate对象，参数为2016年2月13日
        LocalDate localDate = LocalDate.of(2016, Month.FEBRUARY, 13);
        System.out.println("当前时间是："+localDate);

        // 计算当前时间4天后的时间
        LocalDate localDate1 = localDate.plusDays(4L);
        System.out.println("四天后的时间："+localDate1);

        // 计算当前时间3周后的时间
        LocalDate localDate2 = localDate.plusWeeks(3L);
        System.out.println("3周后的时间："+localDate2);

        // 计算当前时间5个月后的时间
        LocalDate localDate3 = localDate.plusMonths(5L);
        System.out.println("5个月后的时间："+localDate3);

        // 计算当前时间2年后的时间
        LocalDate localDate4 = localDate.plusYears(2L);
        System.out.println("2年后的时间："+localDate4);
    }

    /**
     * plus方法在LocalTime中的使用
     *
     * LocalTime中定义了多种对事件进行增减操作的方法
     *
     * LocalTime plusNanos(long nanos) 增加纳秒
     *
     * LocalTime plusSeconds(long seconds) 增加秒
     *
     * LocalTime plusMinutes(long minutes) 增加分钟
     *
     * LocalTime plusHours(long hours) 增加小时
     */

    private static void test4(){
        // 封装LocalTime对象参数为8点14分39秒218纳秒
        LocalTime localTimeNow = LocalTime.of(8, 14, 39, 218);
        System.out.println("localTimeNow = " + localTimeNow);
        // 计算当前时间500纳秒之后的时间
        LocalTime localTime = localTimeNow.plusNanos(500);
        System.out.println("localTime = " + localTime);
        // 计算当前时间45秒后的时间
        LocalTime localTime1 = localTime.plusSeconds(45);
        System.out.println("localTime1 = " + localTime1);
        // 计算当前时间19分钟后的时间
        LocalTime localTime2 = localTime.plusMinutes(19);
        System.out.println("localTime2 = " + localTime2);
        // 计算当前时间3小时后的时间
        LocalTime localTime3 = localTime.plusHours(3);
        System.out.println("localTime3 = " + localTime3);

    }

    /**
     * plus的单独使用方式1
     * <p>
     *
     *本文中都是使用plusXXX的方法进行演示，实际上也有对应的减少方法，以minus开头的方法对应的即为减少，实际上也有对应的减少方法，
     * 以minus开头的方法对应的即为减少，实际上minus方法调用的也是plus方法，只不过传入的参数是负数。
     *
     * plus 和 minus 方法的应用
     *
     * 刚才学习到的plusXXX相关的方法都是添加了数值到具体的某一项上，根据观察还有两个单独的plus方法，接下来我们来学习这两个单独的plus方法。
     *
     * plus(long amountToadd, TemporalUnit unit) LocalTime
     *
     * plus(TemporalAmount amoutToadd) LocalTime
     *
     * TemporalAmount 是一个接口，当接口作为方法的参数的时候，实际上传入的是接口的实现类对象，根据查看这个接口的体系，可以看到这个接口有一个实现类，名字叫做Period，在学习第一节的时候，说明了这个 嘞表示一段时间。
     */

    private static void test5(){
        // 需求：今天程序员小张查看自己的车辆保险记录的时候看到还有2年3个月8天就到期了，小张想计算到期时间是什么时候

        // 封装当前时间
        LocalDateTime localDateTimeNow = LocalDateTime.now();
        System.out.println("当前时间 ： " + localDateTimeNow);
        // 在当前时间的基础上，进行+2年，+3个月，+8天的操作，然后得到一个截至日期对象，这个截至日期对象就是保险到期的时间
        LocalDateTime insuranceExpirationDate = localDateTimeNow.plusYears(2).plusMonths(3).plusDays(8);
        System.out.println("InsuranceExpirationDate = " + insuranceExpirationDate);

        Period period = Period.of(2, 3, 8);
        LocalDateTime insuranceExpirationDate1 = localDateTimeNow.plus(period);
        System.out.println("当前时间是："+localDateTimeNow+"，保险到期时间是："+insuranceExpirationDate1);

    }

    /**
     * plus的单独使用方式2
     */
    private static void test6(){
        // 需求：结婚日期如下，十年之后是锡婚，那么十年之后是什么时候呢？如果我想在十年之后的一天半后请大家吃饭，这个时间又是多少？
        LocalDateTime localDateTimeNow = LocalDateTime.of(LocalDate.of(2022, Month.FEBRUARY, 2), LocalTime.of(11, 11,11));
        System.out.println("结婚的时间："+localDateTimeNow);

        // 10年之后(使用plusYears()方法计算)
        // LocalDateTime time = localDateTimeNow.plusYears(10);
        // System.out.println("十年之后："+time);

        // 10年之后(使用plus(long amountToAdd,TemporalUnit unit)方法计算)
        LocalDateTime time = localDateTimeNow.plus(1, ChronoUnit.DECADES);
        System.out.println("十年之后："+time);

        // 10年之后的半天(使用plusHours方法计算)
        // LocalDateTime eatTime = time.plusHours(12);
        // System.out.println("吃饭时间 ： " + eatTime);

        // 10年之后(使用plus(long amountToAdd,TemporalUnit unit)方法计算)
        LocalDateTime eatTime = time.plus(1, ChronoUnit.HALF_DAYS);
        System.out.println("吃饭时间 ： " + eatTime);

    }

    /**
     * with方法的使用，在LocalDate,LocalTime,LocalDateTime中都有定义
     * with方法使用了调整一个已经存在的时间的
     */
    private static void test7(){
        // 从别处获取到了一个LocalDateTime对象，但是这个对象所表示的日期时间中的日可能存在错误（正确的日应该是每个月的1号）
        LocalDateTime time = getTime();
        // 我想把上面得到的日期时间对象中的日改成1号
        LocalDateTime resultTime = time.withDayOfMonth(1);
        System.out.println("错误的日期："+time);
        System.out.println("正确的日期："+resultTime);

        // 也可以通过如下方式修改
        LocalDateTime resultTime1 = time.with(ChronoField.DAY_OF_MONTH, 1);
        System.out.println("错误的日期："+time);
        System.out.println("正确的日期："+resultTime1);
    }

    private static LocalDateTime getTime() {
        return LocalDateTime.of(1999, Month.DECEMBER, 12, 12, 12,0);
    }


    public static void main(String[] args) {
        test1();
        System.out.println("-------");
        test2();
        System.out.println("-------");
        test3();
        System.out.println("-------");
        test4();
        System.out.println("-------");
        test5();
        System.out.println("-------");
        test6();
        System.out.println("-------");
        test7();
    }
}
